package com.xxl.job.admin.utils;

import com.google.common.collect.Sets;
import com.job.common.DTO.NodeJobDTO;
import org.apache.commons.lang3.StringUtils;

import java.util.HashSet;
import java.util.Map;

/**
 * @author songsong
 * @version 1.0
 * @date 2023/1/13 9:55
 **/
public class NodeCheckUtil {

    /**
     * 校验路径是否有环，有环返回true
     *
     * @param parentId        父节点id
     * @param ids             路径上的id集合
     * @param nodeIdContainer 遍历过的节点集合
     * @param nodeMap         节点map
     * @return
     */
    public static boolean invalidPath(Integer parentId, HashSet<Integer> ids, HashSet<Integer> nodeIdContainer, Map<Integer, NodeJobDTO.Node> nodeMap) {
        // 递归出口（出现之前的节点则代表有环，失败；）
        NodeJobDTO.Node parentNode = nodeMap.get(parentId);
        if (ids.contains(parentNode.getId())) {
            return true;
        }
        nodeIdContainer.add(parentNode.getId());
        //  递归出口 (没有子节点，说明此路径已到底)
        if (StringUtils.isEmpty(parentNode.getChildJobIds())) {
            return false;
        }
        ids.add(parentNode.getId());
        //从节点map中获得此节点的子节点信息，遍历，然后递归检验路径
        String[] childJobIds = parentNode.getChildJobIds().split(",");
        for (int i = 0; i < childJobIds.length; i++) {
            int childJobId = Integer.valueOf(childJobIds[i]);
            if (invalidPath(childJobId, Sets.newHashSet(ids), nodeIdContainer, nodeMap)) {
                return true;
            }
        }
        return false;
    }
}
